# -*- coding: utf-8 -*-

#-------------------------------------------------------------------------------
# Name:        tests sudoku_solver 2.0
# Purpose:
#
# Author:      Alexey
#
# Created:     17.04.2014
# Copyright:   (c) Alexey Zakharenkov 2014
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import sudoku_solver2
import unittest

class SimpleSudokuTests(unittest.TestCase):
    solvedField = [
                    [8, 1, 4,  6, 5, 9,  7, 3, 2],
                    [2, 3, 9,  8, 7, 1,  6, 4, 5],
                    [6, 5, 7,  2, 4, 3,  8, 1, 9],

                    [4, 6, 3,  1, 9, 5,  2, 8, 7],
                    [1, 9, 8,  7, 2, 6,  4, 5, 3],
                    [7, 2, 5,  4, 3, 8,  9, 6, 1],

                    [3, 8, 2,  9, 1, 4,  5, 7, 6],
                    [5, 7, 6,  3, 8, 2,  1, 9, 4],
                    [9, 4, 1,  5, 6, 7,  3, 2, 8]
                  ]
    def _test(self, puzzleField):
        solvedPuzzle = sudoku_solver2.SudokuPuzzle(puzzleField)
        solvedPuzzle.solve()
        correctPuzzle = sudoku_solver2.SudokuPuzzle(self.solvedField)
        self.assertEqual(solvedPuzzle, correctPuzzle)

    def test_zero_row0(self):
        puzzleField = [
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row1(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row2(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row3(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row4(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row5(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row6(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row7(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_row8(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [0, 0, 0,  0, 0, 0,  0, 0, 0]
                      ]
        self._test(puzzleField)



    def test_zero_column0(self):
        puzzleField = [
                        [0, 1, 4,  6, 5, 9,  7, 3, 2],
                        [0, 3, 9,  8, 7, 1,  6, 4, 5],
                        [0, 5, 7,  2, 4, 3,  8, 1, 9],

                        [0, 6, 3,  1, 9, 5,  2, 8, 7],
                        [0, 9, 8,  7, 2, 6,  4, 5, 3],
                        [0, 2, 5,  4, 3, 8,  9, 6, 1],

                        [0, 8, 2,  9, 1, 4,  5, 7, 6],
                        [0, 7, 6,  3, 8, 2,  1, 9, 4],
                        [0, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_column1(self):
        puzzleField = [
                        [8, 0, 4,  6, 5, 9,  7, 3, 2],
                        [2, 0, 9,  8, 7, 1,  6, 4, 5],
                        [6, 0, 7,  2, 4, 3,  8, 1, 9],

                        [4, 0, 3,  1, 9, 5,  2, 8, 7],
                        [1, 0, 8,  7, 2, 6,  4, 5, 3],
                        [7, 0, 5,  4, 3, 8,  9, 6, 1],

                        [3, 0, 2,  9, 1, 4,  5, 7, 6],
                        [5, 0, 6,  3, 8, 2,  1, 9, 4],
                        [9, 0, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_column7(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 0, 2],
                        [2, 3, 9,  8, 7, 1,  6, 0, 5],
                        [6, 5, 7,  2, 4, 3,  8, 0, 9],

                        [4, 6, 3,  1, 9, 5,  2, 0, 7],
                        [1, 9, 8,  7, 2, 6,  4, 0, 3],
                        [7, 2, 5,  4, 3, 8,  9, 0, 1],

                        [3, 8, 2,  9, 1, 4,  5, 0, 6],
                        [5, 7, 6,  3, 8, 2,  1, 0, 4],
                        [9, 4, 1,  5, 6, 7,  3, 0, 8]
                      ]
        self._test(puzzleField)

    def test_zero_column8(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 0],
                        [2, 3, 9,  8, 7, 1,  6, 4, 0],
                        [6, 5, 7,  2, 4, 3,  8, 1, 0],

                        [4, 6, 3,  1, 9, 5,  2, 8, 0],
                        [1, 9, 8,  7, 2, 6,  4, 5, 0],
                        [7, 2, 5,  4, 3, 8,  9, 6, 0],

                        [3, 8, 2,  9, 1, 4,  5, 7, 0],
                        [5, 7, 6,  3, 8, 2,  1, 9, 0],
                        [9, 4, 1,  5, 6, 7,  3, 2, 0]
                      ]
        self._test(puzzleField)

    def test_zero_box_0_0(self):
        puzzleField = [
                        [0, 0, 0,  6, 5, 9,  7, 3, 2],
                        [0, 0, 0,  8, 7, 1,  6, 4, 5],
                        [0, 0, 0,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)

    def test_zero_box_0_1(self):
        puzzleField = [
                        [8, 1, 4,  0, 0, 0,  7, 3, 2],
                        [2, 3, 9,  0, 0, 0,  6, 4, 5],
                        [6, 5, 7,  0, 0, 0,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_0_2(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  0, 0, 0],
                        [2, 3, 9,  8, 7, 1,  0, 0, 0],
                        [6, 5, 7,  2, 4, 3,  0, 0, 0],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_1_0(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [0, 0, 0,  1, 9, 5,  2, 8, 7],
                        [0, 0, 0,  7, 2, 6,  4, 5, 3],
                        [0, 0, 0,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_1_1(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  0, 0, 0,  2, 8, 7],
                        [1, 9, 8,  0, 0, 0,  4, 5, 3],
                        [7, 2, 5,  0, 0, 0,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_1_2(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  0, 0, 0],
                        [1, 9, 8,  7, 2, 6,  0, 0, 0],
                        [7, 2, 5,  4, 3, 8,  0, 0, 0],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_2_0(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [0, 0, 0,  9, 1, 4,  5, 7, 6],
                        [0, 0, 0,  3, 8, 2,  1, 9, 4],
                        [0, 0, 0,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_2_1(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  0, 0, 0,  5, 7, 6],
                        [5, 7, 6,  0, 0, 0,  1, 9, 4],
                        [9, 4, 1,  0, 0, 0,  3, 2, 8]
                      ]
        self._test(puzzleField)


    def test_zero_box_2_2(self):
        puzzleField = [
                        [8, 1, 4,  6, 5, 9,  7, 3, 2],
                        [2, 3, 9,  8, 7, 1,  6, 4, 5],
                        [6, 5, 7,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  1, 9, 5,  2, 8, 7],
                        [1, 9, 8,  7, 2, 6,  4, 5, 3],
                        [7, 2, 5,  4, 3, 8,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  0, 0, 0],
                        [5, 7, 6,  3, 8, 2,  0, 0, 0],
                        [9, 4, 1,  5, 6, 7,  0, 0, 0]
                      ]
        self._test(puzzleField)


class SimpleSudokuTests2(unittest.TestCase):
    solvedField = [
                    [8, 1, 4,  6, 5, 9,  7, 3, 2],
                    [2, 3, 9,  8, 7, 1,  6, 4, 5],
                    [6, 5, 7,  2, 4, 3,  8, 1, 9],

                    [4, 6, 3,  1, 9, 5,  2, 8, 7],
                    [1, 9, 8,  7, 2, 6,  4, 5, 3],
                    [7, 2, 5,  4, 3, 8,  9, 6, 1],

                    [3, 8, 2,  9, 1, 4,  5, 7, 6],
                    [5, 7, 6,  3, 8, 2,  1, 9, 4],
                    [9, 4, 1,  5, 6, 7,  3, 2, 8]
                  ]

    def _test(self, puzzleField):
        solvedPuzzle = sudoku_solver2.SudokuPuzzle(puzzleField)
        solvedPuzzle.solve()
        correctPuzzle = sudoku_solver2.SudokuPuzzle(self.solvedField)
        self.assertEqual(solvedPuzzle, correctPuzzle)

    def test1(self):
        puzzleField = [
                        [0, 0, 0,  6, 5, 9,  7, 3, 2],
                        [0, 0, 0,  8, 7, 1,  6, 4, 5],
                        [0, 0, 0,  2, 4, 3,  8, 1, 9],

                        [4, 6, 3,  0, 0, 0,  2, 8, 7],
                        [1, 9, 8,  0, 0, 0,  4, 5, 3],
                        [7, 2, 5,  0, 0, 0,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  0, 0, 0],
                        [5, 7, 6,  3, 8, 2,  0, 0, 0],
                        [9, 4, 1,  5, 6, 7,  0, 0, 0]
                      ]
        self._test(puzzleField)

    def test2(self):
        puzzleField = [
                        [0, 0, 0,  6, 5, 9,  7, 3, 2],
                        [0, 0, 0,  8, 7, 1,  0, 4, 0],
                        [0, 0, 0,  2, 4, 3,  0, 0, 9],

                        [4, 6, 3,  0, 0, 0,  2, 8, 7],
                        [1, 9, 8,  0, 0, 0,  4, 5, 3],
                        [7, 2, 5,  0, 0, 0,  9, 6, 1],

                        [3, 8, 2,  9, 1, 4,  5, 7, 6],
                        [5, 7, 6,  3, 8, 2,  1, 9, 4],
                        [9, 4, 1,  5, 6, 7,  3, 2, 8]
                      ]
        self._test(puzzleField)


class RealTests(unittest.TestCase):
    solvedFields = [
                      [
                        [3, 1, 5,  8, 9, 6,  2, 7, 4],
                        [2, 8, 6,  7, 3, 4,  1, 9, 5],
                        [9, 4, 7,  5, 2, 1,  3, 6, 8],

                        [1, 5, 4,  2, 6, 3,  9, 8, 7],
                        [8, 9, 2,  1, 7, 5,  4, 3, 6],
                        [6, 7, 3,  9, 4, 8,  5, 1, 2],

                        [7, 2, 8,  4, 1, 9,  6, 5, 3],
                        [4, 6, 9,  3, 5, 7,  8, 2, 1],
                        [5, 3, 1,  6, 8, 2,  7, 4, 9]
                      ],
                      [
                        [4, 2, 3,  5, 9, 6,  1, 8, 7],
                        [6, 5, 9,  8, 1, 7,  2, 3, 4],
                        [8, 1, 7,  4, 3, 2,  9, 5, 6],
                        [3, 8, 1,  6, 7, 9,  5, 4, 2],
                        [5, 4, 6,  1, 2, 8,  7, 9, 3],
                        [9, 7, 2,  3, 5, 4,  8, 6, 1],
                        [7, 6, 4,  2, 8, 5,  3, 1, 9],
                        [2, 3, 5,  9, 6, 1,  4, 7, 8],
                        [1, 9, 8,  7, 4, 3,  6, 2, 5]
                      ]
                   ]
    def _test(self, puzzleField, i):
        solvedPuzzle = sudoku_solver2.SudokuPuzzle(puzzleField)
        solvedPuzzle.solve()
        correctPuzzle = sudoku_solver2.SudokuPuzzle(self.solvedFields[i])
        self.assertEqual(solvedPuzzle, correctPuzzle)

    def test(self):
        puzzleFields = [
                          [
                            [3, 1, 0,  0, 0, 0,  0, 0, 0],
                            [0, 0, 0,  0, 0, 4,  0, 9, 0],
                            [0, 0, 0,  0, 0, 0,  0, 6, 0],

                            [0, 0, 4,  0, 0, 0,  0, 8, 0],
                            [0, 0, 0,  1, 7, 0,  0, 0, 0],
                            [0, 0, 0,  0, 0, 0,  0, 0, 2],

                            [0, 0, 8,  0, 0, 9,  0, 0, 3],
                            [4, 6, 0,  0, 0, 0,  0, 0, 1],
                            [0, 0, 0,  0, 0, 0,  7, 0, 0]
                          ],
                          [
                            [4, 2, 0,  0, 0, 0,  0, 0, 0],
                            [0, 0, 0,  0, 0, 7,  0, 3, 0],
                            [8, 0, 0,  0, 0, 0,  0, 0, 0],

                            [0, 0, 1,  0, 0, 9,  0, 0, 0],
                            [0, 0, 6,  0, 0, 0,  0, 0, 3],
                            [0, 0, 0,  0, 0, 0,  8, 0, 0],

                            [0, 6, 0,  2, 8, 0,  0, 0, 0],
                            [0, 0, 5,  0, 0, 0,  0, 7, 0],
                            [0, 0, 0,  0, 4, 0,  0, 0, 5]
                          ]
                      ]
        for i in range(len(puzzleFields)):
            self._test(puzzleFields[i], i)


if __name__ == "__main__":
    unittest.main()
